import random
import sqlite3
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
import subprocess
import json
import zipfile
import os 
import time
import zipfile
from tkinter import filedialog, messagebox, ttk 


class ServerManager:
    def __init__(self):
        self.db_name = 'servers.db'
        self.conn = sqlite3.connect(self.db_name)
        self.cursor = self.conn.cursor()
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS servers (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                ip TEXT NOT NULL,
                username TEXT NOT NULL,
                password TEXT NOT NULL,
                notes TEXT
            )
        ''')
        self.conn.commit()

    def add_server(self, data):
        try:
            self.cursor.execute('''
                INSERT INTO servers (name, ip, username, password, notes)
                VALUES (?, ?, ?, ?, ?)
            ''', (
                data['name'],
                data['ip'],
                data['username'],
                data['password'],
                data.get('notes', '')
            ))
            self.conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error adding server: {e}")
            return False

    def get_all_servers(self):
        try:
            self.cursor.execute("SELECT * FROM servers")
            rows = self.cursor.fetchall()
            return [{'id': row[0], 'name': row[1], 'ip': row[2], 
                     'username': row[3], 'password': row[4], 
                     'notes': row[5]} for row in rows]
        except sqlite3.Error as e:
            print(f"Error getting servers: {e}")
            return []

    def update_server(self, server_id, data):
        try:
            self.cursor.execute('''
                UPDATE servers
                SET name = ?, ip = ?, username = ?, password = ?, notes = ?
                WHERE id = ?
            ''', (
                data['name'],
                data['ip'],
                data['username'],
                data['password'],
                data.get('notes', ''),
                server_id
            ))
            self.conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error updating server: {e}")
            return False

    def delete_server(self, server_id):
        try:
            self.cursor.execute("DELETE FROM servers WHERE id = ?", (server_id,))
            self.conn.commit()
            return True
        except sqlite3.Error as e:
            print(f"Error deleting server: {e}")
            return False

class App:
    def __init__(self, root):
        self.root = root
        self.servers = []
        self.server_manager = ServerManager()
        self.current_server = None
        
        # 窗口设置
        self.root.title("远程桌面管理工具")
        self.root.geometry("450x350")
        self.root.resizable(False, False)  # 去掉最大化按钮
        
        # 创建菜单栏
        self.create_menu_bar()
        
        # 主框架
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.pack(fill="both", expand=True, padx=10, pady=10)
        
        # 标题标签
        self.title_label = ttk.Label(self.main_frame, text="", font=("Arial", 12, "bold"))
        self.title_label.pack(pady=(0, 10))

        # 初始化动态时间更新
        self.update_time()
        
        # 搜索功能
        self.search_frame = ttk.Frame(self.main_frame)
        self.search_frame.pack(fill="x", pady=(0, 10))
        
        ttk.Label(self.search_frame, text="搜索:").pack(side="left", padx=(0, 5))
        self.search_entry = ttk.Entry(self.search_frame)
        self.search_entry.pack(side="left", fill="x", expand=True)
        self.search_entry.bind("<KeyRelease>", self.on_search_entry_changed)
        
        # 表格显示服务器信息
        tree_frame = ttk.Frame(self.main_frame)
        tree_frame.pack(fill="both", expand=True)
        
        self.tree = ttk.Treeview(tree_frame, columns=(
            "#", "名称", "IP地址", "账户", "备注"), show="headings", height=8)
        
        # 设置表格列标题和宽度
        self.tree.heading("#1", text="#")
        self.tree.column("#1", width=30, anchor="center")
        self.tree.heading("#2", text="名称")
        self.tree.column("#2", width=80)
        self.tree.heading("#3", text="IP地址")
        self.tree.column("#3", width=80)
        self.tree.heading("#4", text="账户")
        self.tree.column("#4", width=60)
        self.tree.heading("#5", text="备注")
        self.tree.column("#5", width=80)
        
        self.tree.pack(fill="both", expand=True)
        
        # 创建右键菜单
        self.tree_menu = tk.Menu(self.tree, tearoff=0)        
        self.tree_menu.add_command(label="连接", command=self.connect_desktop) 
        self.tree_menu.add_command(label="编辑", command=self.edit_server)
        self.tree_menu.add_command(label="删除", command=self.delete_server)
        # 绑定右键事件
        self.tree.bind("<Button-3>", self.show_tree_menu)
        
        # 底部操作按钮
        btn_frame = ttk.Frame(self.main_frame)
        btn_frame.pack(fill="x", pady=(10, 0))
        
         # 标题标签
        title_label = ttk.Label(self.main_frame, text="表格空白处右键点击选择操作功能，选择行执行相应功能", font=("Arial", 8, "bold"))
        title_label.pack(pady=(0, 10))
        
        # 初始化服务器列表
        self.refresh_server_list()
    
    def show_tree_menu(self, event):
        selected_item = self.tree.identify_row(event.y)
        if selected_item:
            self.current_server = selected_item
        self.tree_menu.post(event.x_root, event.y_root)
    
    def update_time(self):
            # 获取当前时间并格式化
        current_time = time.strftime("%Y年%m月%d日 %H:%M:%S")
        self.title_label.config(text=current_time)
        # 每隔1000毫秒（1秒）更新一次时间
        self.root.after(1000, self.update_time)

       
    def create_menu_bar(self):
        menu_bar = tk.Menu(self.root)
        self.root.config(menu=menu_bar)
        file_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="新增记录", command=self.add_server)
        menu_bar.add_cascade(label="全量打包", command=self.pack_files)
        menu_bar.add_cascade(label="更新打包", command=self.pack_files_by_small)
        menu_bar.add_cascade(label="批量操作", menu=file_menu)        
        file_menu.add_command(label="导入服务器列表", command=self.import_servers)
        file_menu.add_command(label="导出服务器列表", command=self.export_servers) 
      
    
    def import_servers(self):
        file_path = filedialog.askopenfilename(filetypes=[("JSON Files", "*.json")])
        if not file_path:
            return
        try:
            with open(file_path, 'r') as f:
                servers = json.load(f)
            for server in servers:
                self.server_manager.add_server(server)
            self.refresh_server_list()
            messagebox.showinfo("成功", "服务器列表导入成功")
        except Exception as e:
            messagebox.showerror("错误", f"导入失败: {e}")
    
    def export_servers(self):
        file_path = filedialog.asksaveasfilename(defaultextension=".json", filetypes=[("JSON Files", "*.json")])
        if not file_path:
            return
        try:
            servers = self.server_manager.get_all_servers()
            with open(file_path, 'w') as f:
                json.dump(servers, f, indent=4)
            messagebox.showinfo("成功", "服务器列表导出成功")
        except Exception as e:
            messagebox.showerror("错误", f"导出失败: {e}")
    
    def refresh_server_list(self): 
        servers = self.server_manager.get_all_servers()
        for server in servers:
            self.tree.insert("", "end", values=(
                server['id'],
                server['name'],
                server['ip'],
                server['username'],
                server['notes']
            ))
    
    def search_servers(self, keyword=None):
        keyword = self.search_entry.get().strip().lower()
        self.tree.delete(*self.tree.get_children())
        servers = self.server_manager.get_all_servers()
        for server in servers:
            if (keyword in server['name'].lower() or
                keyword in server['ip'].lower() or
                keyword in server['username'].lower() or
                keyword in server['notes'].lower()):
                self.tree.insert("", "end", values=(
                    server['id'],
                    server['name'],
                    server['ip'],
                    server['username'],
                    server['notes']
                ))
    
    def on_search_entry_changed(self, event):
        self.search_servers()
    
    def add_server(self):
        self.open_add_edit_dialog(title="新增服务器")
    
    def edit_server(self):
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showerror("错误", "请先选择一个服务器进行编辑")
            return
        server_id = self.tree.item(selected_item)['values'][0]
        server_info = self.server_manager.get_all_servers()
        for server in server_info:
            if server['id'] == server_id:
                self.current_server = server
                break
        else:
            messagebox.showerror("错误", "找不到服务器信息")
            return
        self.open_add_edit_dialog(title="编辑服务器", data=self.current_server)
    
    def open_add_edit_dialog(self, title, data=None):
        dialog = tk.Toplevel(self.root)
        dialog.title(title)
        dialog.geometry("300x260")
        dialog.resizable(True, True)
        
        def on_save():
            name = entry_name.get().strip()
            ip = entry_ip.get().strip()
            username = entry_username.get().strip()
            password = entry_password.get().strip()
            notes = entry_notes.get().strip()
            if not all([name, ip, username, password]):
                messagebox.showerror("输入错误", "请填写所有字段")
                return
            server_data = {
                'name': name,
                'ip': ip,
                'username': username,
                'password': password,
                'notes': notes
            }
            if title == "新增服务器":
                if self.server_manager.add_server(server_data):
                    messagebox.showinfo("成功", "服务器信息已添加")
                    self.refresh_server_list()
                    dialog.destroy()
                else:
                    messagebox.showerror("失败", "无法添加服务器")
            else:
                if self.server_manager.update_server(self.current_server['id'], server_data):
                    messagebox.showinfo("成功", "服务器信息已更新")
                    self.refresh_server_list()
                    dialog.destroy()
                else:
                    messagebox.showerror("失败", "无法更新服务器")
        
        label_name = ttk.Label(dialog, text="服务器名称:")
        label_name.grid(row=0, column=0, padx=5, pady=5)
        entry_name = ttk.Entry(dialog)
        entry_name.grid(row=0, column=1, padx=5, pady=5)
        
        label_ip = ttk.Label(dialog, text="IP地址:")
        label_ip.grid(row=1, column=0, padx=5, pady=5)
        entry_ip = ttk.Entry(dialog)
        entry_ip.grid(row=1, column=1, padx=5, pady=5)
        
        label_username = ttk.Label(dialog, text="用户名:")
        label_username.grid(row=2, column=0, padx=5, pady=5)
        entry_username = ttk.Entry(dialog)
        entry_username.grid(row=2, column=1, padx=5, pady=5)
        
        label_password = ttk.Label(dialog, text="密码:")
        label_password.grid(row=3, column=0, padx=5, pady=5)
        entry_password = ttk.Entry(dialog)
        entry_password.grid(row=3, column=1, padx=5, pady=5)
        
        label_notes = ttk.Label(dialog, text="备注:")
        label_notes.grid(row=4, column=0, padx=5, pady=5)
        entry_notes = ttk.Entry(dialog)
        entry_notes.grid(row=4, column=1, padx=5, pady=5)
        
        button_save = ttk.Button(dialog, text="保存", command=on_save)
        button_save.grid(row=5, column=0, columnspan=2, padx=5, pady=10)
        
        if data:
            entry_name.insert(0, data['name'])
            entry_ip.insert(0, data['ip'])
            entry_username.insert(0, data['username'])
            entry_password.insert(0, data['password'])
            entry_notes.insert(0, data.get('notes', ''))
    
    def delete_server(self):
        selected_item = self.tree.selection()
        if not selected_item:
            return
        server_id = self.tree.item(selected_item)['values'][1]
        if messagebox.askyesno("确认", f"确定要删除服务器 {server_id} 吗？"):
            if self.server_manager.delete_server(server_id):
                self.refresh_server_list()
    
    def connect_desktop(self):
        selected_item = self.tree.selection()
        if not selected_item:
            messagebox.showerror("错误", "请先选择一个服务器")
            return
        server_id = self.tree.item(selected_item)['values'][0]
        servers = self.server_manager.get_all_servers()
        for server in servers:
            if server['id'] == server_id:
                ip = server['ip']
                username = server['username']
                password = server['password'] 
                command = f"mstsc /v:{ip} /admin /f"
            
                try:
                    subprocess.Popen(command)                 
                except Exception as e:
                    messagebox.showerror("连接失败", f"连接失败: {e}")
                break

    def pack_files(self):        
        start_time = time.time()
        directory = filedialog.askdirectory()
        if not directory:
            return
        folder_name = os.path.basename(directory)
        zip_filename = os.path.join(directory, f"{folder_name}.zip")
        total_files = 0
        file_list =[]
        for root, _, files in os.walk(directory):
            if root != directory:
                continue  # 跳过子目录 
            for file in files: 
                if file.endswith(('.dll', '.xml','.exe','.deps.json')):
                    file_path = os.path.join(root, file)
                    file_list.append(file_path)
                    total_files += 1 
        progress = 0
        progress_dialog = tk.Toplevel(self.root)
        progress_dialog.title("打包进度")
        progress_dialog.geometry("200x80")
        progress_var = tk.DoubleVar()
        progress_bar = ttk.Progressbar(progress_dialog, variable=progress_var, maximum=100)
        progress_bar.pack(pady=10)
        progress_label = ttk.Label(progress_dialog, text="打包进度: 0%")
        progress_label.pack()
        def update_progress(current, total):
            percent = (current / total) * 100
            progress_var.set(percent)
            progress_label.config(text=f"打包进度: {percent:.1f}%")
            progress_dialog.update_idletasks()
        current_file = 0
        with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:           
              for file in file_list: 
                    zipf.write(file, os.path.relpath(file, directory)) 
                    current_file += 1
                    update_progress(current_file,total_files)
        end_time = time.time()  # 记录结束时间
        elapsed_time = end_time - start_time  # 计算耗时
        progress_dialog.destroy()
        messagebox.showinfo("成功", f"打包完成: {zip_filename}\n打包文件数: {current_file}\n耗时: {elapsed_time:.2f}秒")
    def pack_files_by_small(self):
        start_time = time.time()  # 记录开始时间
        directory = filedialog.askdirectory()
        if not directory:
            return
        folder_name = os.path.basename(directory)
        zip_filename = os.path.join(directory, f"{folder_name}.zip")
        total_files = 0  
        one_day_ago = start_time - 24 * 60 * 60  # 24小时前的时间戳
        file_list =[]
        for root, dirs, files in os.walk(directory):                
                if root != directory:
                    continue  # 跳过子目录
                for file in files:
                    modify_time = os.path.getmtime(os.path.join(root, file))
                    if file.endswith(('.dll', '.xml','.exe','.deps.json')) and modify_time > one_day_ago:
                        file_path = os.path.join(root, file)
                        file_list.append(file_path)
                        total_files += 1
                        
        progress_dialog = tk.Toplevel(self.root)
        progress_dialog.title("打包进度")
        progress_dialog.geometry("200x80")
        progress_var = tk.DoubleVar()
        progress_bar = ttk.Progressbar(progress_dialog, variable=progress_var, maximum=100)
        progress_bar.pack(pady=10)
        progress_label = ttk.Label(progress_dialog, text="打包进度: 0%")
        progress_label.pack()
        def update_progress(current, total):
            percent = (current / total) * 100
            progress_var.set(percent)
            progress_label.config(text=f"打包进度: {percent:.1f}%")
            progress_dialog.update_idletasks()
        current_file = 0
        with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:     
                for file in file_list: 
                    zipf.write(file, os.path.relpath(file, directory)) 
                    current_file += 1
                    update_progress(current_file,total_files)
        end_time = time.time()  # 记录结束时间
        elapsed_time = end_time - start_time  # 计算耗时
        progress_dialog.destroy()
        messagebox.showinfo("成功", f"打包完成: {zip_filename}\n打包文件数: {current_file}\n耗时: {elapsed_time:.2f}秒")
   
if __name__ == "__main__":
    root = tk.Tk()
    style = ttk.Style()
    style.configure("TButton", padding=(0, 2))
    style.configure("TLabel", padding=(0, 2))
    app = App(root)
    root.mainloop()